home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gnumake / make360.zoo / job.c < prev    next >
C/C++ Source or Header  |  1991-11-11  |  35KB  |  1,493 lines

  1. /* Job execution and handling for GNU Make.
  2. Copyright (C) 1988-1991 Free Software Foundation, Inc.
  3. This file is part of GNU Make.
  4.  
  5. GNU Make is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9.  
  10. GNU Make is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with GNU Make; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "make.h"
  20. #include "commands.h"
  21. #include "job.h"
  22. #include "file.h"
  23. #include "variable.h"
  24. #include <errno.h>
  25.  
  26. /* Default path to search for executables.  */
  27. #ifdef atarist
  28. static char default_path[] = ";/bin";
  29. #else
  30. static char default_path[] = ":/bin:/usr/bin";
  31. #endif
  32.  
  33. /* Default shell to use.  */
  34. char default_shell[] = "/bin/sh";
  35.  
  36. extern int errno;
  37.  
  38. #if    defined(USG) && !defined(HAVE_VFORK)
  39. #define    vfork    fork
  40. #define    VFORK_NAME    "fork"
  41. #else    /* Have vfork or not USG.  */
  42. #define    VFORK_NAME    "vfork"
  43. #endif    /* USG and don't have vfork.  */
  44. extern int vfork ();
  45.  
  46. #ifdef    _POSIX_SOURCE
  47. #include <sys/wait.h>
  48.  
  49. #define    WAIT_NOHANG(status)    waitpid(-1, (status), WNOHANG)
  50.  
  51. #else    /* Not _POSIX_SOURCE.  */
  52.  
  53. #if    defined(HAVE_SYS_WAIT) || !defined(USG)
  54. #include <sys/wait.h>
  55. #include <sys/time.h>
  56. #include <sys/resource.h>
  57.  
  58. #ifndef    wait3
  59. extern int wait3 ();
  60. #endif
  61. #define    WAIT_NOHANG(status)    wait3((status), WNOHANG, (struct rusage *) 0)
  62.  
  63. #ifndef    wait
  64. extern int wait ();
  65. #endif
  66. #endif    /* HAVE_SYS_WAIT || !USG */
  67. #endif    /* _POSIX_SOURCE.  */
  68.  
  69. #if    defined(WTERMSIG) || (defined(USG) && !defined(HAVE_SYS_WAIT))
  70. #define    WAIT_T int
  71.  
  72. #ifndef    WTERMSIG
  73. #define WTERMSIG(x) ((x) & 0x7f)
  74. #endif
  75. #ifndef    WCOREDUMP
  76. #define WCOREDUMP(x) ((x) & 0x80)
  77. #endif
  78. #ifndef    WEXITSTATUS
  79. #define WEXITSTATUS(x) (((x) >> 8) & 0xff)
  80. #endif
  81. #ifndef    WIFSIGNALED
  82. #define WIFSIGNALED(x) (WTERMSIG (x) != 0)
  83. #endif
  84. #ifndef    WIFEXITED
  85. #define WIFEXITED(x) (WTERMSIG (x) == 0)
  86. #endif
  87.  
  88. #else    /* WTERMSIG not defined and have <sys/wait.h> or not USG.  */
  89.  
  90. #ifdef atarist
  91. #  define WAIT_T int
  92. #  define WTERMSIG(x) 0
  93. #  define WCOREDUMP(x) 0
  94. #  define WEXITSTATUS(x)  x
  95. #  define WIFSIGNALED(x) (WTERMSIG (x) != 0)
  96. #  define WIFEXITED(x) (WTERMSIG (x) == 0)
  97. #  undef WAIT_NOHANG
  98. #else
  99. #define WAIT_T union wait
  100. #define WTERMSIG(x)    ((x).w_termsig)
  101. #define WCOREDUMP(x)    ((x).w_coredump)
  102. #define WEXITSTATUS(x)    ((x).w_retcode)
  103. #endif /* atarist */
  104. #ifndef    WIFSIGNALED
  105. #define    WIFSIGNALED(x)    (WTERMSIG(x) != 0)
  106. #endif
  107. #ifndef    WIFEXITED
  108. #define    WIFEXITED(x)    (WTERMSIG(x) == 0)
  109. #endif
  110.  
  111. #endif    /* WTERMSIG defined or USG and don't have <sys/wait.h>.  */
  112.  
  113.  
  114. #if    defined(__GNU_LIBRARY__) || defined(_POSIX_SOURCE)
  115. #include <sys/types.h>
  116. #define    GID_T    gid_t
  117. #ifdef    hpux
  118. #include <sys/param.h>
  119. #define getdtablesize() NOFILE
  120. #endif
  121. #else    /* Not GNU C library.  */
  122.  
  123. #define    GID_T    int
  124.  
  125. extern int dup2 ();
  126. extern int fork (), execve ();
  127. extern void _exit ();
  128. extern int geteuid (), getegid ();
  129. extern int setgid (), getgid ();
  130.  
  131. #ifndef USG
  132. extern int getdtablesize ();
  133. #else
  134. #include <sys/param.h>
  135. #define getdtablesize() NOFILE
  136. #endif
  137. #endif    /* GNU C library.  */
  138.  
  139.  
  140. extern void wait_to_start_job ();
  141. extern int start_remote_job_p ();
  142. extern int start_remote_job (), remote_status ();
  143.  
  144.  
  145. #if    (defined(USG) && !defined(HAVE_SIGLIST)) || defined(DGUX)
  146. static char *sys_siglist[NSIG];
  147. void init_siglist ();
  148. #else    /* Not (USG and HAVE_SIGLIST), or DGUX.  */
  149. extern char *sys_siglist[];
  150. #endif    /* USG and not HAVE_SIGLIST, or DGUX.  */
  151.  
  152. int child_handler ();
  153. static void free_child (), start_job ();
  154.  
  155. /* Chain of all children.  */
  156.  
  157. struct child *children = 0;
  158.  
  159. /* Number of children currently running.  */
  160.  
  161. unsigned int job_slots_used = 0;
  162.  
  163. /* Nonzero if the `good' standard input is in use.  */
  164.  
  165. static int good_stdin_used = 0;
  166.  
  167. /* Write an error message describing the exit status given in
  168.    EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
  169.    Append "(ignored)" if IGNORED is nonzero.  */
  170.  
  171. static void
  172. child_error (target_name, exit_code, exit_sig, coredump, ignored)
  173.      char *target_name;
  174.      int exit_code, exit_sig, coredump;
  175.      int ignored;
  176. {
  177.   char *ignore_string = ignored ? " (ignored)" : "";
  178.  
  179.   if (exit_sig == 0)
  180.     error ("*** [%s] Error %d%s", target_name, exit_code, ignore_string);
  181.   else
  182.     {
  183.       char *coredump_string = coredump ? " (core dumped)" : "";
  184.       if (exit_sig > 0 && exit_sig < NSIG)
  185.     error ("*** [%s] %s%s",
  186.            target_name, sys_siglist[exit_sig], coredump_string);
  187.       else
  188.     error ("*** [%s] Signal %d%s", target_name, exit_sig, coredump_string);
  189.     }
  190. }
  191.  
  192. extern void block_remote_children (), unblock_remote_children ();
  193.  
  194. extern int fatal_signal_mask;
  195.  
  196. #ifdef    USG
  197. /* Set nonzero in the interval when it's possible that we may see a dead
  198.    child that's not in the `children' chain.  */
  199. static int unknown_children_possible = 0;
  200. #endif
  201.  
  202.  
  203. /* Block the child termination signal and fatal signals.  */
  204.  
  205. static void
  206. block_signals ()
  207. {
  208. #ifdef USG
  209.  
  210.   /* Tell child_handler that it might see children that aren't yet
  211.      in the `children' chain.  */
  212.   unknown_children_possible = 1;
  213.  
  214.   /* Ignoring SIGCLD makes wait always return -1.
  215.      Using the default action does the right thing.  */
  216.   (void) SIGNAL (SIGCLD, SIG_DFL);
  217.  
  218. #else    /* Not USG.  */
  219.  
  220.   /* Block the signals.  */
  221. #ifndef atarist
  222.   (void) sigblock (fatal_signal_mask | sigmask (SIGCHLD));
  223. #endif /* atarist */
  224.  
  225. #endif
  226.  
  227.   block_remote_children ();
  228. }
  229.  
  230. /* Unblock the child termination signal and fatal signals.  */
  231. static void
  232. unblock_signals ()
  233. {
  234. #ifdef    USG
  235.  
  236.   (void) SIGNAL (SIGCLD, child_handler);
  237.  
  238.   /* It should no longer be possible for children not in the chain to die.  */
  239.   unknown_children_possible = 0;
  240.  
  241. #else    /* Not USG.  */
  242.  
  243.   /* Unblock the signals.  */
  244. #ifndef atarist
  245.   (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask | sigmask (SIGCHLD)));
  246. #endif
  247.  
  248. #endif
  249.  
  250.   unblock_remote_children ();
  251. }
  252.  
  253. static char *signals_blocked_p_stack = 0;
  254. static unsigned int signals_blocked_p_max;
  255. static unsigned int signals_blocked_p_depth;
  256.  
  257. /* Make signals blocked in FLAG is nonzero, unblocked if FLAG is zero.
  258.    Push this setting on the signals_blocked_p_stack, so it can be
  259.    popped off by pop_signals_blocked_p.  */
  260.  
  261. void
  262. push_signals_blocked_p (flag)
  263.      int flag;
  264. {
  265.   int blocked;
  266.  
  267.   if (signals_blocked_p_stack == 0)
  268.     {
  269.       signals_blocked_p_max = 8;
  270.       signals_blocked_p_stack = (char *) xmalloc (8);
  271.       signals_blocked_p_depth = 1;
  272.       signals_blocked_p_stack[0] = flag;
  273.  
  274.       blocked = 0;
  275.     }
  276.   else
  277.     {
  278.       if (signals_blocked_p_depth == signals_blocked_p_max)
  279.     {
  280.       signals_blocked_p_max += 8;
  281.       signals_blocked_p_stack
  282.         = (char *) xrealloc(signals_blocked_p_stack,
  283.                 signals_blocked_p_max);
  284.     }
  285.  
  286.       blocked = (signals_blocked_p_depth > 0
  287.          && signals_blocked_p_stack[signals_blocked_p_depth - 1]);
  288.  
  289.       signals_blocked_p_stack[++signals_blocked_p_depth - 1] = flag;
  290.     }
  291.  
  292.   if (blocked && !flag)
  293.     unblock_signals ();
  294.   else if (flag && !blocked)
  295.     block_signals ();
  296. }
  297.  
  298. /* Pop the signals_blocked_p setting from the stack
  299.    and block or unblock signals as appropriate.  */
  300.  
  301. void
  302. pop_signals_blocked_p ()
  303. {
  304.   int blocked, block;
  305.  
  306.   blocked = (signals_blocked_p_depth > 0
  307.          && signals_blocked_p_stack[signals_blocked_p_depth-- - 1]);
  308.  
  309.   block = (signals_blocked_p_depth > 0
  310.        && signals_blocked_p_stack[signals_blocked_p_depth - 1]);
  311.  
  312.   if (block && !blocked)
  313.     block_signals ();
  314.   else if (blocked && !block)
  315.     unblock_signals ();
  316. }
  317.  
  318. extern int shell_function_pid, shell_function_completed;
  319.  
  320. /* Handle a child-termination signal (SIGCHLD, or SIGCLD for USG),
  321.    storing the returned status and the new command state (`cs_finished')
  322.    in the `file' member of the `struct child' for the dead child,
  323.    and removing the child from the chain.
  324.  
  325.    If we were called as a signal handler, SIG should be SIGCHLD
  326.    (SIGCLD for USG).  If instead it is zero, we were called explic